#include "halcon_opencv.h"
Mat himageToMat(HObject& imgHalcon)
{
    if (!imgHalcon.IsInitialized())
    {
        return Mat(100, 100, CV_8UC3);
    }
    HTuple hv_n;
    HObject empty;
    GenEmptyObj(&empty);
    TestEqualObj(imgHalcon, empty, &hv_n);
    if (hv_n == 1) //两个Obj相等
    {
        return Mat(100, 100, CV_8UC3);
    }

    HTuple channels;
    HString cType;
    cv::Mat Image;
    ConvertImageType(imgHalcon, &imgHalcon, "byte");
    CountChannels(imgHalcon, &channels);
    Hlong width = 0;
    Hlong height = 0;
    if (channels[0].I() == 1)
    {
        HImage hImg(imgHalcon);
        void* ptr = hImg.GetImagePointer1(&cType, &width, &height);//GetImagePointer1(Hobj, &ptr, &cType, &wid, &hgt);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC1);
        unsigned char* pdata = static_cast<unsigned char*>(ptr);
        memcpy(Image.data, pdata, W * H);
    }
    else if (channels[0].I() == 3)
    {
        void* Rptr;
        void* Gptr;
        void* Bptr;
        HImage hImg(imgHalcon);
        hImg.GetImagePointer3(&Rptr, &Gptr, &Bptr, &cType, &width, &height);
        int W = width;
        int H = height;
        Image.create(H, W, CV_8UC3);
        std::vector<cv::Mat> VecM(3);
        VecM[0].create(H, W, CV_8UC1);
        VecM[1].create(H, W, CV_8UC1);
        VecM[2].create(H, W, CV_8UC1);
        unsigned char* R = (unsigned char*)Rptr;
        unsigned char* G = (unsigned char*)Gptr;
        unsigned char* B = (unsigned char*)Bptr;
        memcpy(VecM[2].data, R, W * H);
        memcpy(VecM[1].data, G, W * H);
        memcpy(VecM[0].data, B, W * H);
        cv::merge(VecM, Image);
    }
    return Image;
}

//Halcon HObjectתOpenCV Mat
HObject matToHImage( Mat& imgMat)
{
    HObject Hobj = HObject();
    int height = imgMat.rows;
    int width = imgMat.cols;
    //  CV_8UC3
    if (imgMat.type() == CV_8UC3)
    {
        std::vector<cv::Mat> vec;
        cv::split(imgMat, vec);

        cv::Mat imgB = vec[0];
        cv::Mat imgG = vec[1];
        cv::Mat imgR = vec[2];

        HalconCpp::HObject himgR,himgG,himgB;
        GenImage1(&himgR, "byte", width, height, (Hlong)imgR.data);
        GenImage1(&himgG, "byte", width, height, (Hlong)imgG.data);
        GenImage1(&himgB, "byte", width, height, (Hlong)imgB.data);
        HalconCpp::Compose3(himgR, himgG, himgB, &Hobj);
    }
    //  CV_8UCU1
    else if (imgMat.type() == CV_8UC1)
    {
        GenImage1(&Hobj, "byte", width, height, (Hlong)imgMat.data);
    }
    return Hobj;
}



Mat drawRegion( Mat mat_image, HObject region, Scalar color)
{
    if (!region.IsInitialized())
    {
        return mat_image;
    }
    HTuple hv_n;
    HObject empty;
    GenEmptyObj(&empty);
    TestEqualObj(region, empty, &hv_n);
    if (hv_n == 1) //两个Obj相等
    {
        return mat_image;
    }

    std::vector<std::vector<Point>> vector_vector_contour;
    HTuple hv_Length;
    HObject xlds;
    GenContourRegionXld(region, &xlds, "border");
    CountObj(xlds, &hv_Length);
    int region_number = hv_Length[0].I();
    for (int j = 1; j <= region_number; j++)
    {
        std::vector<Point> vector_contour;
        HObject xld;
        HTuple HTuplerow, HTuplecolumn, HTuplelength;
        SelectObj(xlds, &xld, j);

        GetContourXld(xld, &HTuplerow, &HTuplecolumn);
        TupleLength(HTuplerow, &HTuplelength);
        int xld_number = HTuplelength[0].I();
        for (int m = 0; m < xld_number; m++)
        {
            Point point;
            point.y = HTuplerow[m].D();
            point.x = HTuplecolumn[m].D();
            vector_contour.push_back(point);
        }
        vector_vector_contour.push_back(vector_contour);
    }
    Mat mat_out = mat_image.clone();
    drawContours(mat_out, vector_vector_contour, -1, color, 3);
    return mat_out;
}

Mat drawRegionFill(Mat mat_image, HObject region, Scalar color)
{
	if (!region.IsInitialized())
	{
		return mat_image;
	}
	HTuple hv_n;
	HObject empty;
	GenEmptyObj(&empty);
	TestEqualObj(region, empty, &hv_n);
	if (hv_n == 1) //两个Obj相等
	{
		return mat_image;
	}

	std::vector<std::vector<Point>> vector_vector_contour;
	HTuple hv_Length;
	HObject xlds;
	GenContourRegionXld(region, &xlds, "border");
	CountObj(xlds, &hv_Length);
	int region_number = hv_Length[0].I();
	for (int j = 1; j <= region_number; j++)
	{
		std::vector<Point> vector_contour;
		HObject xld;
		HTuple HTuplerow, HTuplecolumn, HTuplelength;
		SelectObj(xlds, &xld, j);

		GetContourXld(xld, &HTuplerow, &HTuplecolumn);
		TupleLength(HTuplerow, &HTuplelength);
		int xld_number = HTuplelength[0].I();
		for (int m = 0; m < xld_number; m++)
		{
			Point point;
			point.y = HTuplerow[m].D();
			point.x = HTuplecolumn[m].D();
			vector_contour.push_back(point);
		}
		vector_vector_contour.push_back(vector_contour);
	}
	Mat mat_out = mat_image.clone();
	drawContours(mat_out, vector_vector_contour, -1, color, -1);
	return mat_out;
}

Mat drawXld( Mat mat_image, HObject xlds, Scalar color)
{
    if (!xlds.IsInitialized())
    {
        return mat_image;
    }
    HTuple hv_n;
    HObject empty;
    GenEmptyObj(&empty);
    TestEqualObj(xlds, empty, &hv_n);
    if (hv_n == 1) //两个Obj相等
    {
        return mat_image;
    }
    Mat mat_out = mat_image.clone();
    //std::vector<std::vector<Point>> vector_vector_contour;
    HTuple hv_Length;
    CountObj(xlds, &hv_Length);
    int region_number = hv_Length[0].I();
    for (int j = 1; j <= region_number; j++)
    {
        //std::vector<Point> vector_contour;
        HObject xld;
        HTuple HTuplerow, HTuplecolumn, HTuplelength;
        SelectObj(xlds, &xld, j);

        GetContourXld(xld, &HTuplerow, &HTuplecolumn);
        TupleLength(HTuplerow, &HTuplelength);
        int xld_number = HTuplelength[0].I();
        for (int m = 0; m < xld_number-1; m++)
        {
            Point point;
            point.y = static_cast<int>(HTuplerow[m].D());
            point.x = static_cast<int>(HTuplecolumn[m].D());
            //vector_contour.push_back(point);
            circle(mat_out, point, 1, color, 1);
        }
        //vector_vector_contour.push_back(vector_contour);
    }
   /* Mat mat_out = mat_image.clone();
    drawContours(mat_out, vector_vector_contour, -1, color, 3);*/
    return mat_out;
}
